package io.geekidea.springbootplus.system.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.service.WxPayService;
import io.geekidea.springbootplus.config.properties.SpringBootPlusProperties;
import io.geekidea.springbootplus.framework.common.api.ApiResult;
import io.geekidea.springbootplus.framework.common.controller.BaseController;
import io.geekidea.springbootplus.framework.core.pagination.PageInfo;
import io.geekidea.springbootplus.framework.core.pagination.Paging;
import io.geekidea.springbootplus.framework.core.validator.groups.Add;
import io.geekidea.springbootplus.framework.core.validator.groups.Update;
import io.geekidea.springbootplus.framework.log.annotation.Module;
import io.geekidea.springbootplus.framework.log.annotation.OperationLog;
import io.geekidea.springbootplus.framework.log.enums.OperationLogType;
import io.geekidea.springbootplus.framework.util.HttpServletRequestUtil;
import io.geekidea.springbootplus.framework.util.IpUtil;
import io.geekidea.springbootplus.framework.util.UploadUtil;
import io.geekidea.springbootplus.system.annotations.CurrentCarrier;
import io.geekidea.springbootplus.system.annotations.CurrentCarrierInfo;
import io.geekidea.springbootplus.system.annotations.CurrentUser;
import io.geekidea.springbootplus.system.constant.TaskStatusConstant;
import io.geekidea.springbootplus.system.entity.*;
import io.geekidea.springbootplus.system.mapper.TaskMapper;
import io.geekidea.springbootplus.system.param.TaskPageParam;
import io.geekidea.springbootplus.system.service.*;
import io.geekidea.springbootplus.system.vo.TaskQueryVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.Current;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.task.TaskSchedulingProperties;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *  控制器
 *
 * @author miko
 * @since 2020-10-10
 */
@Slf4j
@RestController
@RequestMapping("/task")
@Module("system")
@Api(value = "API", tags = {""})
public class TaskControllerExtra extends BaseController {

    @Autowired
    private TaskService taskService;

    @Autowired
    private TaskTempService taskTempService;

    @Autowired
    private AddressService addressService;

    @Autowired
    private SpringBootPlusProperties springBootPlusProperties;

    @Autowired
    ParcelCenterCoService parcelCenterCoService;

    @Resource
    TaskMapper taskMapper;

    @Autowired
    SubscribeMessageService subscribeMessageService;

    @Autowired
    CustomerService customerService;

    @Autowired
    WxPayService wxPayService;


    /**
     * 修改
     */
    @PostMapping("/notice")
    @OperationLog(name = "修改", type = OperationLogType.UPDATE)
    @ApiOperation(value = "修改", response = ApiResult.class)
    public ApiResult<Object> notice(@RequestBody String xmlData) throws Exception {
        final WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
        String id = notifyResult.getAttach();

        TaskTemp taskTemp = taskTempService.getOne(new LambdaQueryWrapper<TaskTemp>().eq(TaskTemp::getTaskID,id).ne(TaskTemp::getStatus,11));

        String s = JSON.toJSONString(taskTemp);

        taskTemp.setStatus(11);

        taskTempService.saveOrUpdate(taskTemp);

        JSONObject jsonObject = JSON.parseObject(s);
        jsonObject.remove("yuan");

        Task task = jsonObject.toJavaObject(Task.class);
        task.setTaskID(null);

        taskService.saveTask(task);
        return ApiResult.ok(null);
    }



    /**
     * 修改
     */
    @PostMapping("/pay")
    @OperationLog(name = "修改", type = OperationLogType.UPDATE)
    @ApiOperation(value = "修改", response = ApiResult.class)
    public ApiResult<Object> pay(@CurrentUser CurrentUserInfo currentUserInfo,@RequestBody TaskTemp task) throws Exception {

        HttpServletRequest request = HttpServletRequestUtil.getRequest();

        String ip = IpUtil.getRequestIp(request);

        String yuan = task.getYuan();

        int schoolID = Integer.parseInt(currentUserInfo.getSchoolID());

        Customer customer = currentUserInfo;

        Address address = addressService.getById(task.getAddressID());

        String addressContactStr = address.getDormitoryName()+"楼 "+address.getFloor()+"层 "+address.getRoom()+"号";

        task.setCustomerID(customer.getCustomerID());

        task.setSubmitTime(new Date());
        task.setAddress(addressContactStr);

        task.setSchoolID(Integer.valueOf(schoolID));
        task.setStatus(TaskStatusConstant.UNTAKE);
        task.setDormitoryName(address.getDormitoryName());
        task.setFloor(address.getFloor());


        ParcelCenterCo parcelCenterCo = parcelCenterCoService.getOne(new LambdaQueryWrapper<ParcelCenterCo>()
                .eq(ParcelCenterCo::getSchoolID,schoolID)
                .eq(ParcelCenterCo::getCoName,task.getCourierCompany()));



        if(parcelCenterCo == null){
            task.setParcelCenterName("其它");
        }else{
            task.setParcelCenterName(parcelCenterCo.getName());
        }

        boolean flag = taskTempService.saveTaskTemp(task);

        TaskTemp taskTemp = taskTempService.getOne(new LambdaQueryWrapper<TaskTemp>().last("LIMIT 1").orderByDesc(TaskTemp::getTaskID));

        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
        orderRequest.setBody("订单");
        orderRequest.setOutTradeNo(String.valueOf(new Date().getTime()));
        orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(yuan));//元转成分
        orderRequest.setOpenid(currentUserInfo.getOpenID());
        orderRequest.setAttach(String.valueOf(taskTemp.getTaskID()));
        orderRequest.setSpbillCreateIp(ip);
        orderRequest.setNotifyUrl("https://api.favormylikes.com/spring/api/task/notice");
        orderRequest.setTradeType(WxPayConstants.TradeType.JSAPI);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");

        Date date = new Date();

        Date afterDate = new Date(date .getTime() + 60000);
        String currentTimeStr = sdf.format(date);
        String expireTimeStr = sdf.format(afterDate);

        orderRequest.setTimeStart(currentTimeStr);
        orderRequest.setTimeExpire(expireTimeStr);

        System.out.println(wxPayService);

        Object o = wxPayService.createOrder(orderRequest);

        return ApiResult.ok(o);

    }


        /**
         * 修改
         */
    @PostMapping("/statistics")
    @OperationLog(name = "修改", type = OperationLogType.UPDATE)
    @ApiOperation(value = "修改", response = ApiResult.class)
    public ApiResult<Map<String,List<Map<String,Object>>>> statistics(@CurrentCarrier CurrentCarrierInfo currentCarrierInfo,@RequestBody JSONObject jsonObject) throws Exception {
        Map<String,List<Map<String,Object>>> map = new HashMap<>();

        String workType = jsonObject.getString("workType");

        int schoolID = currentCarrierInfo.getSchool().getSchoolID();

        int carrierID = currentCarrierInfo.getCarrier().getCarrierID();

        QueryWrapper<Task> wrapper = new QueryWrapper<>();


        if(workType.equals("取件员")){
            wrapper.select("DATE_FORMAT(createTime, '%Y%m%d') days,count(taskid) count")
                    .eq("SchoolID",schoolID)
                    .eq("TakePersonId",carrierID)
                    .groupBy("days").orderByDesc("days").last("limit 5");

            List<Map<String,Object>> list = taskMapper.selectMaps(wrapper);
            map.put("days",list);

            wrapper = new QueryWrapper<>();
            wrapper.select("DATE_FORMAT(createTime, '%Y%u') weeks,count(taskid) count")
                    .eq("SchoolID",schoolID)
                    .eq("TakePersonId",carrierID)
                    .groupBy("weeks").orderByDesc("weeks").last("limit 5");
            list = taskMapper.selectMaps(wrapper);
            map.put("weeks",list);

            wrapper = new QueryWrapper<>();
            wrapper.select("DATE_FORMAT(createTime, '%Y%m') months,count(taskid) count")
                    .eq("SchoolID",schoolID)
                    .eq("TakePersonId",carrierID)
                    .groupBy("months").orderByDesc("months").last("limit 5");

            list = taskMapper.selectMaps(wrapper);
            map.put("months",list);

        }else{
            wrapper.select("DATE_FORMAT(createTime, '%Y%m%d') days,count(taskid) count")
                    .eq("SchoolID",schoolID)
                    .eq("SendPersonId",carrierID)
                    .groupBy("days").orderByDesc("days").last("limit 5");

            List<Map<String,Object>> list = taskMapper.selectMaps(wrapper);
            map.put("days",list);

            wrapper = new QueryWrapper<>();
            wrapper.select("DATE_FORMAT(createTime, '%Y%u') weeks,count(taskid) count")
                    .eq("SchoolID",schoolID)
                    .eq("SendPersonId",carrierID)
                    .groupBy("weeks").orderByDesc("weeks").last("limit 5");
            list = taskMapper.selectMaps(wrapper);
            map.put("weeks",list);

            wrapper = new QueryWrapper<>();
            wrapper.select("DATE_FORMAT(createTime, '%Y%m') months,count(taskid) count")
                    .eq("SchoolID",schoolID)
                    .eq("SendPersonId",carrierID)
                    .groupBy("months").orderByDesc("months").last("limit 5");

            list = taskMapper.selectMaps(wrapper);
            map.put("months",list);
        }

        return ApiResult.ok(map);
    }



//    /**
//     * 添加
//     */
//    @PostMapping("/submit")
//    @OperationLog(name = "提交任务", type = OperationLogType.ADD)
//    @ApiOperation(value = "提交任务", response = ApiResult.class)
//    public ApiResult<Boolean> addTask(@RequestBody Task task, @CurrentUser CurrentUserInfo currentUserInfo) throws Exception {
//
//        return ApiResult.result(flag);
//    }




    /**
     * 添加
     */
    @PostMapping("/getTodoTask")
    @OperationLog(name = "提交任务", type = OperationLogType.ADD)
    @ApiOperation(value = "提交任务", response = ApiResult.class)
    public ApiResult<List<Task>> getTodoTask(@CurrentCarrier CurrentCarrierInfo currentCarrierInfo, @RequestBody JSONObject jsonObject) throws Exception {
        int schoolID = currentCarrierInfo.getSchool().getSchoolID();

        String searchText = jsonObject.getString("searchText");

        Date deadLine = new Date();

        String parcelCenterName = jsonObject.getString("parcelCenterName");

        String dormitoryName = jsonObject.getString("dormitoryName");

        String workType = jsonObject.getString("workType");
        String period = jsonObject.getString("period");

        if(period.equals("0")){
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

            String s = simpleDateFormat.format(deadLine);
            s = s+" 12:00:00";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            deadLine = sdf.parse(s);
        }
        if(workType.equals("取件员")){
            List<Task> list = taskService.getToDoAndDoneTask(schoolID,parcelCenterName,deadLine,workType,searchText);
            return ApiResult.ok(list);
        }else {
            List<Task> list = taskService.getToDoAndDoneTask(schoolID,dormitoryName,deadLine,workType,searchText);
            return ApiResult.ok(list);
        }
    }




    /**
     * 修改
     */
    @PostMapping("/uploadTakeCredentials")
    @OperationLog(name = "修改", type = OperationLogType.UPDATE)
    @ApiOperation(value = "修改", response = ApiResult.class)
    public ApiResult<Boolean> updateTask(@RequestParam("file") MultipartFile file,
                                         @RequestParam("taskID") int taskID
            ,@CurrentCarrier CurrentCarrierInfo currentCarrierInfo) throws Exception {
        Task task = taskService.getById(taskID);
        task.setTakePersonId(currentCarrierInfo.getCarrier().getCarrierID());
        task.setTakePersonName(currentCarrierInfo.getCarrier().getPersonName());
        task.setTakeTime(new Date());

        // 上传文件，返回保存的文件名称
        String saveFileName = UploadUtil.upload(springBootPlusProperties.getUploadPath(), file, originalFilename -> {
            // 文件后缀
            String fileExtension = FilenameUtils.getExtension(originalFilename);
            // 这里可自定义文件名称，比如按照业务类型/文件格式/日期
            String dateString = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssS")) + RandomStringUtils.randomNumeric(6);
            String fileName = dateString + "." + fileExtension;
            return fileName;
        });

        task.setTakeCredentials(saveFileName);
        task.setStatus(TaskStatusConstant.TAKED_UNSEND);

        boolean flag = taskService.updateTask(task);

        Customer customer = customerService.getById(task.getCustomerID());
        if(customer!=null){
            subscribeMessageService.sendMessage(customer,task,currentCarrierInfo.getCarrier(),"网点已提件");
        }
        return ApiResult.result(flag);
    }



    @PostMapping("/confirmSend")
    @OperationLog(name = "修改", type = OperationLogType.UPDATE)
    @ApiOperation(value = "修改", response = ApiResult.class)
    public ApiResult<Boolean> updateSendTask(@CurrentCarrier CurrentCarrierInfo currentCarrierInfo,
                                             @RequestBody JSONObject jsonObject) throws Exception {
        int taskID = Integer.parseInt(jsonObject.getString("taskID"));

        Task task = taskService.getById(taskID);

        task.setSendPersonId(currentCarrierInfo.getCarrier().getCarrierID());
        task.setSendPersonName(currentCarrierInfo.getCarrier().getPersonName());
        task.setSendTime(new Date());
        task.setStatus(TaskStatusConstant.SENDING);
        boolean flag = taskService.updateTask(task);

        Customer customer = customerService.getById(task.getCustomerID());

        subscribeMessageService.sendMessage(customer,task,currentCarrierInfo.getCarrier(),"已送至楼下");
        return ApiResult.result(flag);
    }



    @PostMapping("/uploadSendCredentials")
    @OperationLog(name = "修改", type = OperationLogType.UPDATE)
    @ApiOperation(value = "修改", response = ApiResult.class)
    public ApiResult<Boolean> updateSendTask(@RequestParam("file") MultipartFile file,
                                         @RequestParam("taskID") int taskID
            ,@CurrentCarrier CurrentCarrierInfo currentCarrierInfo) throws Exception {
        Task task = taskService.getById(taskID);
        task.setSendPersonId(currentCarrierInfo.getCarrier().getCarrierID());
        task.setSendPersonName(currentCarrierInfo.getCarrier().getPersonName());
        task.setSendTime(new Date());

        // 上传文件，返回保存的文件名称
        String saveFileName = UploadUtil.upload(springBootPlusProperties.getUploadPath(), file, originalFilename -> {
            // 文件后缀
            String fileExtension = FilenameUtils.getExtension(originalFilename);
            // 这里可自定义文件名称，比如按照业务类型/文件格式/日期
            String dateString = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssS")) + RandomStringUtils.randomNumeric(6);
            String fileName = dateString + "." + fileExtension;
            return fileName;
        });

        task.setSendCredentials(saveFileName);
        task.setStatus(TaskStatusConstant.SENDING);

        boolean flag = taskService.updateTask(task);
        return ApiResult.result(flag);
    }

    /**
     * 修改
     */
    @PostMapping("/uploadInnerSendCredentials")
    @OperationLog(name = "修改", type = OperationLogType.UPDATE)
    @ApiOperation(value = "修改", response = ApiResult.class)
    public ApiResult<Boolean> updateInnerSendTask(@RequestParam("file") MultipartFile file,
                                             @RequestParam("taskID") int taskID
            ,@CurrentCarrier CurrentCarrierInfo currentCarrierInfo) throws Exception {
        Task task = taskService.getById(taskID);
        task.setInnerSendPersonId(currentCarrierInfo.getCarrier().getCarrierID());
        task.setInnerSendPersonName(currentCarrierInfo.getCarrier().getPersonName());
        task.setInnerSendTime(new Date());

        // 上传文件，返回保存的文件名称
        String saveFileName = UploadUtil.upload(springBootPlusProperties.getUploadPath(), file, originalFilename -> {
            // 文件后缀
            String fileExtension = FilenameUtils.getExtension(originalFilename);
            // 这里可自定义文件名称，比如按照业务类型/文件格式/日期
            String dateString = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssS")) + RandomStringUtils.randomNumeric(6);
            String fileName = dateString + "." + fileExtension;
            return fileName;
        });

        task.setInnerSendCredentials(saveFileName);
        task.setStatus(TaskStatusConstant.COMPLETE);

        boolean flag = taskService.updateTask(task);

        Customer customer = customerService.getById(task.getCustomerID());

        subscribeMessageService.sendMessage(customer,task,currentCarrierInfo.getCarrier(),"已送至门口");

        return ApiResult.result(flag);
    }

    /**
     * 分页列表
     */
    @PostMapping("/getSdHistory")
    @OperationLog(name = "获取捎带列表", type = OperationLogType.PAGE)
    @ApiOperation(value = "获取捎带列表", response = Task.class)
    public ApiResult<Paging<Task>> getTaskPageList(@Validated @RequestBody TaskPageParam taskPageParam, @CurrentUser CurrentUserInfo currentUserInfo) throws Exception {

        int schoolID = Integer.parseInt(currentUserInfo.getSchoolID());

        int customerID = currentUserInfo.getCustomerID();

        LambdaQueryWrapper<Task> wrapper = new LambdaQueryWrapper();
        wrapper.eq(Task::getSchoolID, schoolID);
        wrapper.eq(Task::getCustomerID, customerID);

        Page<Task> page = new PageInfo<>(taskPageParam, OrderItem.desc("CreateTime"));

        IPage<Task> iPage = taskService.page(page,wrapper);

        Paging<Task> d = new Paging<Task>(iPage);
        return ApiResult.ok(d);
    }

    /**
     * 分页列表
     */
    @PostMapping("/getCarrierHistory")
    @OperationLog(name = "获取捎带列表", type = OperationLogType.PAGE)
    @ApiOperation(value = "获取捎带列表", response = Task.class)
    public ApiResult<List<Task>> getTaskPageList(@CurrentCarrier CurrentCarrierInfo currentCarrierInfo,@RequestBody JSONObject jsonObject) throws Exception {

        String workType = jsonObject.getString("workType");

        String searchText = jsonObject.getString("searchText");

        int schoolID = currentCarrierInfo.getSchool().getSchoolID();

        int carrierID = currentCarrierInfo.getCarrier().getCarrierID();

        LambdaQueryWrapper<Task> wrapper = new LambdaQueryWrapper();
        wrapper.eq(Task::getSchoolID, schoolID).orderByDesc(Task::getCreateTime);

        if(workType.equals("取件员")){
            wrapper.eq(Task::getTakePersonId, carrierID);
        }else{
            wrapper.and(w->{
                w.eq(Task::getSendPersonId,carrierID).or().eq(Task::getInnerSendPersonId, carrierID);
            });
        }

        if(!StringUtils.isEmpty(searchText)){
            wrapper.and(w->{w.like(Task::getAddress,searchText).or().like(Task::getPhone, searchText).or().like(Task::getPickupCode, searchText); });
        }

        List<Task> list = taskService.list(wrapper);

        return ApiResult.ok(list);
    }

    /**
     * 分页列表
     */
    @PostMapping("/getCarrierHistorySize")
    @OperationLog(name = "获取捎带列表", type = OperationLogType.PAGE)
    @ApiOperation(value = "获取捎带列表", response = Task.class)
    public ApiResult<Integer> getTaskPageListSize(@CurrentCarrier CurrentCarrierInfo currentCarrierInfo,@RequestBody  JSONObject jsonObject) throws Exception {

        String workType = jsonObject.getString("workType");

        String searchText = jsonObject.getString("searchText");

        int schoolID = currentCarrierInfo.getSchool().getSchoolID();

        int carrierID = currentCarrierInfo.getCarrier().getCarrierID();

        LambdaQueryWrapper<Task> wrapper = new LambdaQueryWrapper();
        wrapper.eq(Task::getSchoolID, schoolID);

        if(workType.equals("取件员")){
            wrapper.eq(Task::getTakePersonId, carrierID);
        }else{
            wrapper.and(w->{
                w.eq(Task::getSendPersonId,carrierID).or().eq(Task::getInnerSendPersonId, carrierID);
            });
        }

        if(!StringUtils.isEmpty(searchText)){
            wrapper.and(w->{w.like(Task::getAddress,searchText).or().like(Task::getPhone, searchText).or().like(Task::getPickupCode, searchText); });
        }

        List<Task> list = taskService.list(wrapper);

        return ApiResult.ok(list.size());
    }


}

